%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% CSP send and receive operations written in Oz

% Author: Peter Van Roy
% Date: March 15, 2007

% How to implement one-shot and many-shot channels in Oz
% that do the CSP rendezvous synchronization

% We give the basic code.  We leave it as an exercise to
% encapsulate this code inside a data abstraction.  This
% can be done either in ADT or object style in an easy way.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% One-shot send-receive

% A channel on which a single value can be sent
% Often a one-shot channel is enough, for example when
% sending an acknowledgement.  The originator sends a 
% message containing a one-shot channel, which is used to
% send the acknowledgement.

% Note that a CSP send operation actually does a by-need
% synchronization: it waits until a receive operation is
% done.  In the Oz solution, we see the by-need explicitly.

% 1. Create channel c
declare C

% 2. Send operation: equivalent to c!some_value
{WaitNeeded C}
C=some_value

% 3. Receive operation: equivalent to c?x
%    C itself is bound to the received value x.
{Wait C}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% Many-shot send-receive

% A channel on which any number of values can be sent
% A true CSP channel

% 1. Create channel 'chan'
declare
local Sstr Rstr in
   Sport={NewPort Sstr}
   Rport={NewPort Rstr}
   thread Sstr=Rstr end
end

% 2. Send operation: equivalent to chan!some_value
local X in
   {Send Sport X}
   {WaitNeeded X}
   X=some_value
end

% 3. Receive operation: equivalent to chan?x
local X in
   {Send Rport X}
   {Wait X}
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
